﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
using System.Web.UI.WebControls;
using System.Collections.Specialized;

namespace Light.Utility
{
    public class EnumHelper
    {

        public static Enum GetEnum(Type enumType, string enumName_OR_enumValue)
        {
            return GetEnum(enumType, enumName_OR_enumValue, null);
        }


        public static Enum GetEnum(Type enumType, string enumName_OR_enumValue, Enum defaultValue)
        {
            if (!enumType.IsEnum)
            {
                return defaultValue;
            }
            int value = -1;
            if (Enum.IsDefined(enumType, enumName_OR_enumValue))
            {
                return (Enum)Enum.Parse(enumType, enumName_OR_enumValue,true);
            }
            else if (int.TryParse(enumName_OR_enumValue, out value))
            {
                return (Enum)Enum.Parse(enumType, enumName_OR_enumValue,true);
            }
            else
            {
                IList descList = GetEnumDescs(enumType, false);

                foreach (KeyValuePair<object, string> item in descList)
                {
                    if (item.Value == enumName_OR_enumValue.Trim())
                        return (Enum)item.Key;
                }

            }

            return defaultValue;
        }

        public static Enum GetEnum<T>(string enumName_OR_enumValue, Enum defaultValue)
        {
            return GetEnum(typeof(T), enumName_OR_enumValue, defaultValue);
        }

        public static bool IsDefined(Type enumType, object obj)
        {
            if (StringHelper.IsNumeric(obj) && Enum.IsDefined(enumType, int.Parse(obj.ToString())))
                return true;
            else
                return Enum.IsDefined(enumType, obj);
        }

        public static bool IsDefined<T>(object obj)
        {
            if (StringHelper.IsNumeric(obj) && Enum.IsDefined(typeof(T), int.Parse(obj.ToString())))
                return true;
            else
                return Enum.IsDefined(typeof(T), obj);
        }



        #region Get Eumn Desc
        /// <summary>
        /// 获取枚举的属性值
        /// </summary>
        /// <param name="enumName">枚举成员</param>
        /// <returns>返回枚举的属性值</returns>
        public static string GetEnumDesc(Enum enumName)
        {
            return GetEnumDesc<DescriptionAttribute>(enumName, true);
        }

        /// <summary>
        /// 获取枚举的属性值
        /// </summary>
        /// <param name="enumName">枚举成员</param>
        /// <param name="isOnly">是否只获取指定属性类型的值</param>
        /// <returns>返回枚举的属性值</returns>
        public static string GetEnumDesc(Enum enumName, bool isOnly)
        {
            return GetEnumDesc<DescriptionAttribute>(enumName, isOnly);
        }

        /// <summary>
        /// 获取枚举的属性值
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="enumName">枚举成员</param>
        /// <returns>返回枚举的属性值</returns>
        public static string GetEnumDesc<T>(Enum enumName)
            where T : DescriptionAttribute
        {
            return GetEnumDesc<T>(enumName, true);
        }

        /// <summary>
        /// 获取枚举的属性值
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="enumName">枚举成员</param>
        /// <param name="isOnly">是否只获取指定的属性类型的值</param>
        /// <returns>返回枚举的属性值</returns>
        public static string GetEnumDesc<T>(Enum enumName, bool isOnly)
            where T : DescriptionAttribute
        {
            FieldInfo info = enumName.GetType().GetField(enumName.ToString());
            if (info == null)
            {
                return "未知";
            }
            T[] attribute = (T[])info.GetCustomAttributes(typeof(T), false);

            if (attribute.Length == 0)
                return enumName.ToString();

            StringBuilder sBuilder = new StringBuilder();
            string desc = string.Empty;
            foreach (T item in attribute)
            {
                if (isOnly)
                {
                    if (typeof(T) != item.GetType())
                    {
                        desc = item.Description;
                        continue;
                    }
                }
                sBuilder.Append("|" + item.Description);
            }

            if (sBuilder.Length > 0)
                sBuilder.Remove(0, 1);
            else if (!string.IsNullOrEmpty(desc))
                sBuilder.Append(desc);
            else
                sBuilder.Append(enumName.ToString());

            return sBuilder.ToString();
        }

        #endregion

        #region Get Enum Descs

        ///// <summary>
        ///// 获取枚举属性值的集合
        ///// </summary>
        ///// <param name="enumType"></param>
        ///// <returns></returns>
        //public static IList GetEnumDescs(Type enumType)
        //{
        //    return GetEumnDescs<DescriptionAttribute>(enumType);
        //}



        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <param name="enumType"></param>
        /// <param name="isOnly">是否仅获取基本属性类型的属性值</param>
        /// <returns></returns>
        private static IList GetEnumDescs(Type enumType, bool isOnly)
        {
            return GetEumnDescs<DescriptionAttribute>(enumType, isOnly);
        }


        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static IList GetEumnDescs<T>(Type enumType)
            where T : DescriptionAttribute
        {
            return GetEumnDescs<T>(enumType, true);
        }


        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="enumType"></param>
        /// <param name="isOnly">是否仅获取指定属性类型的属性值</param>
        /// <returns></returns>
        public static IList GetEumnDescs<T>(Type enumType, bool isOnly)
            where T : DescriptionAttribute
        {
            return GetEumnDescs<T>(enumType, isOnly, false);
        }


        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="enumType"></param>
        /// <param name="isOnly">是否仅获取指定属性类型的属性值</param>
        /// <param name="onlyDesc">结果集中，是否仅返回属性值</param>
        /// <returns></returns>
        private static IList GetEumnDescs<T>(Type enumType, bool isOnly, bool onlyDesc)
            where T : DescriptionAttribute
        {
            if (enumType == null)
                return null;

            if (!enumType.IsEnum)
                return null;

            ArrayList list = new ArrayList();
            Array array = Enum.GetValues(enumType);

            foreach (Enum value in array)
            {
                if (onlyDesc)
                    list.Add(GetEnumDesc<T>(value, isOnly));
                else
                {
                    list.Add(new KeyValuePair<object, string>((Enum.Parse(value.GetType(), value.ToString())), GetEnumDesc<T>(value, isOnly)));
                }
            }

            return list;
        }


        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <returns></returns>
        public static Dictionary<string, int> GetEnumDescs<T>()
        {
            return GetEnumDescsExcept<T>(null);
        }


        public static IList<KeyValuePair<string, int>> GetEnumDescsToList<T>()
        {
            Dictionary<string, int> dic = GetEnumDescs<T>();

            List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();


            foreach (var key in dic.Keys)
            {
                list.Add(new KeyValuePair<string, int>(key, dic[key]));
            }
            return list;
        }


        /// <summary>
        /// 获取枚举属性值的集合
        /// </summary>
        /// <typeparam name="T">指定所要获取属性值的属性类型</typeparam>
        /// <param name="itemsExcept">排除指定的项</param>
        /// <returns></returns>
        public static Dictionary<string, int> GetEnumDescsExcept<T>(params Enum[] itemsExcept)
        {
            Type enumType = typeof(T);

            if (enumType == null)
                return null;

            if (!enumType.IsEnum)
                return null;

            Dictionary<string, int> list = new Dictionary<string, int>();

            Array array = Enum.GetValues(enumType);
            List<Enum> listExcept = new List<Enum>();

            if (itemsExcept != null)
            {
                listExcept.AddRange(itemsExcept);
            }

            foreach (Enum item in array)
            {
                if (listExcept.Contains(item))
                    continue;

                string enumDesc = GetEnumDesc(item);
                int enumValue = (int)Enum.Parse(item.GetType(), item.ToString());

                list.Add(enumDesc, enumValue);
            }
            return list;
        }


        /// <summary>
        /// 获取枚举Description特性值的集合
        /// </summary>
        /// <param name="itemsInclude">包含的项</param>
        /// <returns></returns>
        public static Dictionary<string, int> GetEnumDescsInclude(params Enum[] itemsInclude)
        {

            Dictionary<string, int> list = new Dictionary<string, int>();

            foreach (Enum item in itemsInclude)
            {
                string enumDesc = GetEnumDesc(item);
                int enumValue = (int)Enum.Parse(item.GetType(), item.ToString());

                list.Add(enumDesc, enumValue);
            }
            return list;
        }


        #endregion

        #region 绑定枚举到下拉列框 BindEnumToDropDownList

        /// <summary>
        /// 绑定枚举到下拉列框 BindEnumToDropDownList
        /// </summary>
        /// <param name="dro"></param>
        public static void BindEnumToDropDownList<T>(DropDownList control)
        {
            IList<KeyValuePair<string, int>> list = EnumHelper.GetEnumDescsToList<T>();
            foreach (var a in list)
            {
                control.Items.Add(new ListItem(a.Key, a.Value.ToString()));
            }
        }
        /// <summary>
        /// 绑定枚举到下拉列框 BindEnumToDropDownList
        /// </summary>
        /// <param name="dro"></param>
        public static void BindEnumToDropDownList<T>(DropDownList control, bool isDefault)
        {
            IList<KeyValuePair<string, int>> list = EnumHelper.GetEnumDescsToList<T>();
            if (isDefault)
            {
                control.Items.Add(new ListItem("请选择", ""));
            }
            foreach (var a in list)
            {
                control.Items.Add(new ListItem(a.Key, a.Value.ToString()));
            }
        }
        #endregion
    }
}
